//
//  ViewController.m
//  Demo
//
//  Created by iOS on 2017/5/24.
//  Copyright © 2017年 MS. All rights reserved.
//

#import "ViewController.h"
#import <Masonry.h>
#import "CustomTableViewCell.h"
#import "Goods.h"

typedef NS_ENUM(NSUInteger, AutoScroll) {
    AutoScrollNone,
    AutoScrollUp,
    AutoScrollDown,
};

static UIView *snapshot;
static NSIndexPath *fromIndexPath;

@interface ViewController () <UITableViewDataSource,UITableViewDelegate,UIGestureRecognizerDelegate>

@property (strong, nonatomic) UITableView *tableView;
@property (strong, nonatomic) NSMutableArray *dataSourceArrM;
@property (nonatomic) CGFloat rowHeight;

@property (strong, nonatomic) UILongPressGestureRecognizer *gesture;
@property (strong, nonatomic) CADisplayLink *displayLink;
@property (nonatomic) CGFloat edgeScrollRange;
@property (nonatomic) AutoScroll autoScroll;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self.view addSubview:self.tableView];
    
    _edgeScrollRange = 120.0f;
}

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    
    [_tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view);
    }];
}


#pragma mark - lazy loading

- (UITableView *)tableView
{
    if (!_tableView)
    {
        _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        
        // 添加长按手势
        _gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(processLongPressGestureAction:)];
        _gesture.delegate = self;
        [_tableView addGestureRecognizer:_gesture];
    }
    
    return _tableView;
}

- (NSMutableArray *)dataSourceArrM
{
    if (!_dataSourceArrM)
    {
        _dataSourceArrM = [[NSMutableArray alloc] initWithArray:[Goods getGoodsDataSource]];
    }
    
    return _dataSourceArrM;
}

- (CADisplayLink *)displayLink
{
    
    if (!_displayLink)
    {
        _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(processScrollTableView)];
        [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    }
    
    return _displayLink;
}


#pragma mark - UITableViewDataSource/UITableViewDelegate

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.dataSourceArrM.count;
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 91.0;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return _rowHeight;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomTableViewCell *cell = [CustomTableViewCell cellWithTableView:tableView];
    
    [cell configCellWithModel:_dataSourceArrM[indexPath.row] indexPath:indexPath];
    _rowHeight = [cell heightForRow];
    
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    
}


#pragma mark - UIGestureRecognizerDelegate

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    CGPoint point = [gestureRecognizer locationInView:_tableView];
    NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:point];
    // 取出手指所在的cell
    CustomTableViewCell *cell = [_tableView cellForRowAtIndexPath:indexPath];
    CGPoint point_cell = [cell convertPoint:point fromView:_tableView];
    
    // 长按longPressMoveImgView，返回YES
    return CGRectContainsPoint(cell.longPressMoveImgView.frame, point_cell);
}


#pragma mark -

- (void)processLongPressGestureAction:(UILongPressGestureRecognizer *)longPressGesture
{
    CGPoint touchPoint = [longPressGesture locationInView:_tableView];
    NSIndexPath *toIndexPath = [_tableView indexPathForRowAtPoint:touchPoint];
    
    switch (longPressGesture.state)
    {
        case UIGestureRecognizerStateBegan:
        {
            if (toIndexPath)
            {
                // 点击有效cell
                fromIndexPath = toIndexPath;
                UITableViewCell *cell = [_tableView cellForRowAtIndexPath:toIndexPath];
                snapshot = [self customSnapshoFromView:cell];
                snapshot.center = cell.center;
                snapshot.alpha = 0.0f;
                
                [_tableView addSubview:snapshot];
                
                // 执行动画
                [UIView animateWithDuration:0.25 animations:^{
                    snapshot.center = CGPointMake(snapshot.center.x, touchPoint.y);
                    snapshot.transform = CGAffineTransformMakeScale(1.05, 1.05);
                    snapshot.alpha = 1.0f;
                    
                    cell.alpha = 0.0f;
                } completion:^(BOOL finished) {
                    cell.hidden = YES;
                }];
            }
            
            break;
        }
        case UIGestureRecognizerStateChanged:
        {
            
            // 快照跟随手指移动
            snapshot.center = CGPointMake(snapshot.center.x, touchPoint.y);
            
            // 边缘滚动处理
            if ([self canEdgeScroll])
            {
                [self startTimerToScrollTableView];
            }
            else
            {
                [self stopScrollTableView];
            }
            
            if (toIndexPath && ![toIndexPath isEqual:fromIndexPath])
            {
                [self insertCell:toIndexPath];
            }
            
            break;
        }
        default:
        {
            UITableViewCell *cell = [_tableView cellForRowAtIndexPath:fromIndexPath];
            cell.hidden = NO;
            
            [UIView animateWithDuration:0.25 animations:^{
                snapshot.center = cell.center;
                snapshot.transform = CGAffineTransformIdentity;
                snapshot.alpha = 0.0f;
                
                cell.alpha = 1.0f;
            } completion:^(BOOL finished) {
                fromIndexPath = nil;
                [snapshot removeFromSuperview];
                snapshot = nil;
            }];
            
            [self stopScrollTableView];
            [_tableView reloadData];
            
            break;
        }
    }
}

/**
 开启定时器滚动表格
 */
- (void)startTimerToScrollTableView
{
    [self displayLink];
}

- (void)processScrollTableView
{
    if ((_autoScroll == AutoScrollUp && _tableView.contentOffset.y  < 0) || (_autoScroll == AutoScrollDown && _tableView.contentOffset.y > _tableView.contentSize.height - CGRectGetHeight(_tableView.frame)))
    {
        [self stopScrollTableView];
        return;
    }
    
    CGPoint touchPoint = [_gesture locationInView:_tableView];
    // 手指在self.view中的坐标
    CGPoint point = [self.view convertPoint:touchPoint fromView:_tableView];
    // 滚动速度
    CGFloat scrollSpeed = fabs(point.y - _edgeScrollRange) / _edgeScrollRange;
    CGFloat height = _autoScroll == AutoScrollUp ? -scrollSpeed : scrollSpeed;
    
    // 改变表的offset，实现自动滚动效果
    _tableView.contentOffset = CGPointMake(_tableView.contentOffset.x, _tableView.contentOffset.y + height);
    // 同步改变snapshot位置
    snapshot.center = CGPointMake(snapshot.center.x, snapshot.center.y + height);
    
    NSIndexPath *toIndexPath = [self indexPathForRowAtPoint:snapshot.center];
    
    if (toIndexPath && ![toIndexPath isEqual:fromIndexPath])
    {
        // 移动cell
        [self insertCell:toIndexPath];
    }
}

/**
 停止滚动
 */
- (void)stopScrollTableView
{
    [_displayLink invalidate];
    _displayLink = nil;
}

/**
 判断能否进行边缘滚动

 @return 返回YES，则进行边缘滚动
 */
- (BOOL)canEdgeScroll
{
    if (CGRectGetMinY(snapshot.frame) < _tableView.contentOffset.y + _edgeScrollRange + _tableView.contentInset.top && _tableView.contentOffset.y > 0)
    {
        _autoScroll = AutoScrollUp;
        return YES;
    }
    else if (CGRectGetMaxY(snapshot.frame) > _tableView.contentOffset.y + CGRectGetHeight(_tableView.frame) - _edgeScrollRange + _tableView.contentInset.bottom && _tableView.contentOffset.y < _tableView.contentSize.height - CGRectGetHeight(_tableView.frame))
    {
        _autoScroll = AutoScrollDown;
        return YES;
    }
    else
    {
        return NO;
    }
}

- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point
{
    return [_tableView indexPathForRowAtPoint:point];
}


/**
 移动cell

 @param toIndexPath 要移动到的目标位置
 */
- (void)insertCell:(NSIndexPath *)toIndexPath
{
    // 交换数据
    [_dataSourceArrM exchangeObjectAtIndex:fromIndexPath.row withObjectAtIndex:toIndexPath.row];
    
    // 移动cell
    [_tableView moveRowAtIndexPath:fromIndexPath toIndexPath:toIndexPath];
    fromIndexPath = toIndexPath;
    
    UITableViewCell *cell = [_tableView cellForRowAtIndexPath:fromIndexPath];
    cell.hidden = YES;
}

#pragma mark - snapshot

/**
 生成inputView的快照
 */
- (UIView *)customSnapshoFromView:(UIView *)inputView
{
    UIView* snapshot = nil;
    
    if ([[[UIDevice currentDevice] systemVersion] doubleValue] < 7.0)
    {
        //ios7.0 以下通过截图形式保存快照
        snapshot = [self customSnapShortFromViewEx:inputView];
    }
    else
    {
        //ios7.0 系统的快照方法
        snapshot = [inputView snapshotViewAfterScreenUpdates:NO];
    }
    
    snapshot.layer.masksToBounds = NO;
    snapshot.layer.cornerRadius = 0.0;
    snapshot.layer.shadowOffset = CGSizeMake(-5.0, 0.0);
    snapshot.layer.shadowRadius = 5.0;
    snapshot.layer.shadowOpacity = 0.4;
    
    return snapshot;
}

- (UIView *)customSnapShortFromViewEx:(UIView *)inputView
{
    CGSize inSize = inputView.bounds.size;
    // 下面方法，第一个参数表示区域大小。第二个参数表示是否是非透明的。如果需要显示半透明效果，需要传NO，否则传YES。第三个参数就是屏幕密度了
    UIGraphicsBeginImageContextWithOptions(inSize, NO, [UIScreen mainScreen].scale);
    [inputView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image= UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    UIImageView* snapshot = [[UIImageView alloc] initWithImage:image];
    
    return snapshot;
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
